import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import PipelineVulnerabilityReport from 'ee/security_dashboard/components/pipeline/pipeline_vulnerability_report.vue';
import VulnerabilityReport from 'ee/security_dashboard/components/shared/vulnerability_report/vulnerability_report.vue';
import FindingModal from 'ee/security_dashboard/components/pipeline/vulnerability_finding_modal.vue';

describe('Pipeline vulnerability report', () => {
  let wrapper;
  const TEST_PIPELINE = { iid: 1 };
  const TEST_PROJECT_FULL_PATH = 'path/to/my/project';

  const createWrapper = () => {
    wrapper = shallowMount(PipelineVulnerabilityReport, {
      provide: {
        pipeline: TEST_PIPELINE,
        projectFullPath: TEST_PROJECT_FULL_PATH,
      },
    });
  };

  const findModal = () => wrapper.findComponent(FindingModal);
  const findReport = () => wrapper.findComponent(VulnerabilityReport);

  it('passes the expected props to the vulnerability report component', () => {
    createWrapper();

    expect(findReport().props()).toMatchObject({
      fields: wrapper.vm.$options.fieldsToShow,
      filterDropdowns: wrapper.vm.$options.filtersToShow,
      filterFn: wrapper.vm.transformFilters,
    });
  });

  describe('filters', () => {
    it.each`
      property        | value                                         | expected
      ${'severity'}   | ${['HIGH', 'LOW']}                            | ${['high', 'low']}
      ${'severity'}   | ${[]}                                         | ${undefined}
      ${'severity'}   | ${undefined}                                  | ${undefined}
      ${'reportType'} | ${['CONTAINER_SCANNING', 'SECRET_DETECTION']} | ${['container_scanning', 'secret_detection']}
      ${'reportType'} | ${[]}                                         | ${undefined}
      ${'reportType'} | ${undefined}                                  | ${undefined}
      ${'state'}      | ${['DETECTED', 'CONFIRMED']}                  | ${['DETECTED', 'CONFIRMED']}
      ${'state'}      | ${[]}                                         | ${[]}
      ${'state'}      | ${undefined}                                  | ${undefined}
    `(
      'formats the filters correctly for the pipeline GraphQL endpoint when $property is $value',
      ({ property, value, expected }) => {
        createWrapper();
        const filters = wrapper.vm.transformFilters({ [property]: value });

        expect(filters).toEqual({ [property]: expected });
        expect(findReport().props('filterFn')).toBe(wrapper.vm.transformFilters);
      },
    );
  });

  describe('finding modal', () => {
    it(`shows the modal when a vulnerability is clicked and hides it when it's supposed to be hidden`, async () => {
      createWrapper();

      expect(findModal().exists()).toBe(false);

      const finding = { id: '1' };
      findReport().vm.$emit('vulnerability-clicked', finding);
      await nextTick();

      expect(findModal().props('findingUuid')).toBe(finding.id);

      findModal().vm.$emit('hidden');
      await nextTick();

      expect(findModal().exists()).toBe(false);
    });
  });
});
